package services

import config._
import dao._

import javax.inject.{Inject, Singleton}
import org.apache.commons.io.FileUtils
import play.api.libs.json.Json
import utils.TableUtils

import scala.collection.mutable
import scala.concurrent.ExecutionContext
import scala.jdk.CollectionConverters._

@Singleton
class OnStart @Inject()(genomeDao: GenomeDao, grnaDao: GrnaDao)(implicit exec: ExecutionContext) extends MyFile with MyRow with MyAwait with MyJson {

//  val genes = genomeDao.getAllGenome.toAwait

//  TableUtils.geneIdToId = genes.map { x => x.geneid -> x.id }.toMap


  val proteomicsFile = s"${Global.path}/config/proteomics.txt".readLines.map(_.split("\t"))

  TableUtils.proteomicsHeader = proteomicsFile.head

  TableUtils.proteomicsGeneId = proteomicsFile.tail.map(_.head).distinct.toSeq
  TableUtils.proteomicsProtein = proteomicsFile.tail.map(_(1)).distinct.filter(_!= "-").toSeq
  TableUtils.proteomicsGeneName = proteomicsFile.tail.map(_(2)).distinct.filter(_!= "-").toSeq

  TableUtils.proteomics  = proteomicsFile.tail.toSeq.map(_.toSeq)
  val genes = genomeDao.getAllGenome.toAwait
/*  val nameMap = Map("MsG0180" -> "Cole01G", "MsG0280" -> "Cole02G", "MsG0380" -> "Cole03G", "MsG0480" -> "Cole04G",
    "MsG0580" -> "Cole05G", "MsG0680" -> "Cole06G", "MsG0780" -> "Cole07G", "MsG0880" -> "Cole08G")

  val c = genes.filter(_.species == "ZMNO").map{x=>
    val n = x.geneid.take(7)
    val r = nameMap.getOrElse(n, n)
    val name = r + x.geneid.split('.').head.drop(7)
    name + "\t"+ x.start + "\t" + x.end + "\t" + x.strand
  }

  FileUtils.writeLines("H:\\南农油茶数据库\\2024_4_8/chr.txt".toFile,c.toBuffer.asJava)*/
  TableUtils.geneIdToId = genes.map { x => x.geneid -> x.id }.toMap
/*

  "H:\\紫花苜蓿数据库\\2024_3_18".listFile.foreach{x=>
    val name = x.getName
     s"${x.getPath}/annotation.table.xls".readLines.tail.map(_.split("\t")).foreach {x=>
      val id = TableUtils.geneIdToId(x.head)
       println(id)
       genomeDao.updateGoAndKegg(id,x(8).replace("-","_"),x(11).replace("-","_")).toAwait
    }

  }
*/


  if (true) {

    val genes = genomeDao.getAllGenome.toAwait

    TableUtils.geneIdToId = genes.map { x => x.geneid -> x.id }.toMap

    TableUtils.genome = genes.groupBy(_.species).map { case (species, genome) =>
      println(species)
      species -> genome.map(_.getMapByT())
    }

    /*  TableUtils.genome.foreach{x=>
        val geneId = x._2.map(_("geneid"))
        FileUtils.writeLines(s"I:\\alfalfa_db\\blastData/${x._1}_geneid.txt".toFile,geneId.toBuffer.asJava)
      }
*/
/*      val genome = genomeDao.getAllGenome.toAwait.groupBy(_.species)

      genome.foreach{x=>
        val go = x._2.filter(_.gos != "-").map(y=> y.geneid +"\t" + y.gos.replaceAll(",",";").trim)
        val kegg = x._2.filter(_.keggKo != "-").map(y=> y.geneid + "\t" + y.keggKo.replaceAll("ko:","").split(",").mkString(";"))
    //    FileUtils.writeLines(s"I:\\alfalfa_db/${x._1}.gene".toFile,x._2.map(_.geneid).asJava)
        FileUtils.writeLines(s"I:\\alfalfa_db/enrich/${x._1}.go.xls".toFile,go.asJava)
        FileUtils.writeLines(s"I:\\alfalfa_db/enrich/${x._1}.kegg.xls".toFile,kegg.asJava)
      }*/

    Search.search = genes.map { x =>
      (x.id, x.species, Seq(x.geneid, x.chr, x.eggnogOgs, x.narrOgName, x.narrOgCat, x.narrOgDesc, x.bestOgName, x.bestOgCat,
        x.bestOgDesc, x.ec, x.keggKo, x.keggPathway, x.keggModule, x.keggReaction, x.keggRclass, x.brite, x.keggTc, x.gos,
        x.preferredName, x.cazy, x.biggReaction, x.pfams).mkString("\t"))
    }


    TableUtils.exampleGeneName = TableUtils.genome.map { case (genome, gene) =>
      (genome, gene.take(20).map(_("geneid")))
    }

    TableUtils.chr = TableUtils.genome.map { x => x._1 -> x._2.map(_("chr")).distinct }

    TableUtils.blocks = s"${Global.path}/block".listFile.flatMap { x =>
      val line = x.readFileToString
      val range = line.split("###").tail
      val name = x.getName.split('.')
      range.zipWithIndex.map { case (y, i) =>
        val genes = y.trim.split("\n").map(_.split("\t")).map(y => y.head.split('.').init.mkString(".") -> y(1).split('.').init.mkString("."))
        val blockName = name.head.toUpperCase + "_vs_" + name(1).toUpperCase + "_" + (i + 1)
        blockName -> genes
      }
    }.toMap

    val rnaRows = s"${Global.path}/RNA-seq".listFile.map { x =>
      val name = x.getName.split('.').head
      val lines = x.readLines
      val head = lines.head.split("\t")
      (name, lines.tail, head)
    }

    TableUtils.rnaRows = rnaRows.map { x =>
      x._1 -> x._2.map { y =>
        y.split("\t").zipWithIndex.map { z =>
          z._2.toString -> z._1
        }.toMap
      }.toSeq
    }.toMap

    TableUtils.rnaHeader = rnaRows.map(x => x._1 -> (Array("Treatment") ++: x._3.tail)).toMap
    TableUtils.rna = rnaRows.flatMap { x =>
      x._2.map(_.split("\t")).map { y =>
        val rnaId = y.head
        val geneId = y.head.split('.').init.mkString(".")
        (geneId, rnaId, x._1, y.tail)
      }
    }.groupBy(_._1).map { case (geneId, info) =>
      geneId -> info.groupBy(_._2).map { case (rnaId, info) =>
        rnaId -> info.map(x => (x._3, x._4.map(_.toDouble)))
      }
    }

    GRNAClock.grnaConfig(grnaDao)
  }

/*
  val lines = s"${Global.path}/config/Zmno.gff".readLines

  val gene = genes.filter(_.species == "ZMNO").map(_.geneid)

  gene.foreach {x=>
    val cds = lines.filter(_.endsWith( x + ".T01"))
    FileUtils.writeLines(s"H:\\紫花苜蓿数据库\\gff\\gene/${x}.txt".toFile,cds.asJava)
  }

*/

  println("变异基因条")

/*
  /**变异基因条**/
  genes.filter(_.species == "ZMNO").foreach { info =>
    val min = Seq(info.start, info.end).min
    val line =  s"H:\\紫花苜蓿数据库\\gff\\gene/${info.geneid}.txt".readLines.map(_.split("\t")).filter(_(2) == "CDS").map { x =>
      Json.obj("from" -> (x(3).toInt - min + 1), "to" -> (x(4).toInt - min + 1), "name" -> "CDS", "zIndex" -> 20, "color" -> "#0083B7")
    }

    FileUtils.writeStringToFile( s"H:\\紫花苜蓿数据库\\gff\\gene2/${info.geneid}.txt".toFile,Json.toJson(line).toString)
  }
*/



/*
  /**变异位点生成**/
 // val genes = genomeDao.getAllGenome.toAwait

  genes.filter(_.species == "ZMNO").foreach { info =>
    val file = s"H:\\紫花苜蓿数据库\\2023_9_22\\网站\\gene/${info.geneid}.txt".toFile
    if (file.exists()) {
      val lines = file.readLines

      val snp = lines.filter(_.startsWith("SNP")).map(_.split("\t").tail)
      val indel = lines.filter(_.startsWith("Indel")).map(_.split("\t").tail)
      val sv = lines.filter(_.startsWith("SV")).map(_.split("\t").tail)
      val min = Seq(info.start, info.end).min

      val snpScatter = Json.obj("name" -> "SNP", "color" -> "#303030", "data" -> snp.map { x =>
        val pos = x(3).toInt
        val name = x(2) + ":" + x(3) + "-" + x(4) + "|REF/ALT:" + x(5) + "/" + x(6) + "|Type:SNP|Allele_frequency:" + x(7)
        val i = pos - min + 1
        Json.obj("name" -> name, "x" -> i, "y" -> 5,"z" -> (x(7).toDouble*100))
      })

      val indelScatter = Json.obj("name" -> "Indel", "color" -> "#7CB5EC", "data" -> indel.map { x =>
        val pos = x(3).toInt
        val name =  x(2) + ":" + x(3) + "-" + x(4) + "|Type:Indel|Allele_frequency:" + x(7)
        val i = pos - min + 1
        Json.obj("name" -> name, "x" -> i, "y" -> 5,"z" -> (x(7).toDouble*100))
      })

      val svScatter = Json.obj("name" -> "SV", "color" -> "#EE7600", "data" -> sv.map { x =>
        val pos = x(3).toInt
        val name = x(2) + ":"+ x(3) + "-" + x(4) + "|Type:SV|Allele_frequency:" + x(7)
        val i = pos - min + 1
        Json.obj("name" -> name, "x" -> i, "y" -> 5,"z" ->  (x(7).toDouble*100))
      })

      val scatter = Json.toJson(Seq(snpScatter, indelScatter, svScatter)).toString


      FileUtils.writeStringToFile(s"H:\\紫花苜蓿数据库\\2023_9_22\\网站\\gene3/${info.geneid}.txt".toFile, scatter)
    }
  }
*/


/*
  /** 变异位点生成-老版本* */
  genes.filter(_.species == "ZMNO").foreach { info =>
    val file = s"H:\\紫花苜蓿数据库\\2023_9_22\\网站\\gene/${info.geneid}.txt".toFile
    if (file.exists()) {
      val lines = file.readLines

      val snp = lines.filter(_.startsWith("SNP")).map(_.split("\t").tail)
      val indel = lines.filter(_.startsWith("Indel")).map(_.split("\t").tail)
      val sv = lines.filter(_.startsWith("SV")).map(_.split("\t").tail)
      val min = Seq(info.start, info.end).min

      val snpScatter = Json.obj("name" -> "SNP", "color" -> "#303030", "data" -> snp.map { x =>
        val pos = x(1).toInt
        val name = x.head + ":" + pos + "|REF/ALT:" + x(3) + "/" + x(4) + "|Type:SNP"
        val i = pos - min + 1
        Json.obj("name" -> name, "x" -> i, "y" -> 5)
      })

      val indelScatter = Json.obj("name" -> "Indel", "color" -> "#7CB5EC", "data" -> indel.map { x =>
        val pos = x(1).toInt
        val name = x.head + ":" + pos + "|Type:Indel"
        val i = pos - min + 1
        Json.obj("name" -> name, "x" -> i, "y" -> 5)
      })

      val svScatter = Json.obj("name" -> "SV", "color" -> "#EE7600", "data" -> sv.map { x =>
        val pos = x(1).toInt
        val name = x.head + ":" + pos + "|Type:SV"
        val i = pos - min + 1
        Json.obj("name" -> name, "x" -> i, "y" -> 5)
      })

      val scatter = Json.toJson(Seq(snpScatter, indelScatter, svScatter)).toString


      FileUtils.writeStringToFile(s"H:\\紫花苜蓿数据库\\2023_9_22\\网站\\gene2/${info.geneid}.txt".toFile, scatter)
    }
  }*/

}
